/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "Sequence.h"

#include <math/utl.h>
#include <xml/Stream.h>
#include <lib3d/hard/Hardware.h>
#include <system/StringFunctions.h>

#include <algorithm>
#include <xml/Saver.h>

namespace liba {
namespace lib3d {
namespace anim2d {

Sequence::Sequence()
	: image_index_length(1)
{ }

Sequence::Sequence(const Sequence& rhs)
	: image_index_length(rhs.image_index_length)
	, AbstractSequence(rhs)
{
	load_image(image_name);
}

AbstractSequence *Sequence::clone() const
{
	return new Sequence(*this);
}

size_t Sequence::get_frames_count() const
{
	return frames.size();
}

void Sequence::render_to_list(hard::Hardware * hardware, hard::RenderTexture * render_texture, unsigned frame_number)
{
	if( frame_number >= frames.size() )
		return;
	frames[frame_number]->render_to_list( hardware, render_texture );
}

bool Sequence::on_attribute(xml::Provider * prov, const std::string & name, const std::string & value)
{
	if (name == "ImageIndexLength")
		return converter::convert(value, &image_index_length);
	return AbstractSequence::on_attribute(prov, name, value);
}

void Sequence::on_save_attributes(xml::SaverBase * saver) const
{
	AbstractSequence::on_save_attributes(saver);

	if(image_index_length != 1)
		saver->save_attribute("ImageIndexLength", image_index_length);
}

void Sequence::load_image( const std::string & image_name )
{
	if(image_name.empty())
		return;

	for(size_t i = 0; i < frames.size(); i++)
		delete frames[i];
	frames.clear();

	int delta = frame_end - frame_start;
	int dir = math::sgn(delta);
	delta = math::abs(delta);
	for( int i = frame_start; delta >= 0; i += dir, --delta )
	{
		material::TextureSimple::Name nam;
		nam.image = filesystem::String( image_name.c_str() );
		char fmt[15];
		system::_snprintf(fmt, 15, "%%0%dd", this->image_index_length); 
		char buf[255];
		system::_snprintf( buf, 255, fmt, i );
		const char * ptr_temp = buf;
		nam.image += ptr_temp;
		nam.wrap = false;
		frames.push_back( new material::TextureSimple(Atom("Diffuse"), nam) );
	}
}

} // namespace anim2d
} // namespace lib3d
} // namespace liba
